/*
 ============================================================================
 Name		: MyDataCenter.cpp
 Author	  : 
 Version	 : 1.0
 Copyright   : copyright readever.cn
 2009-2010
 Description : CMyDataCenter implementation
 iHtmlControlֻ��һ�����ã�����������ʵ��������plugin����Щ
 ============================================================================
 */
#include <ImageConversion.h> 

#include <html\htmlcontrol.h> 
#include <html\lirenderer.h>

#include <AKNAPPUI.h>
#include <bautils.h>
#include <EIKENV.H>
#include <EIKAPPUI.h>
#include <utf.h>

#include "CStreamAudioEngine.h"
#include "mk4.h"
#include "mk4str.h"
#include "MyUtils.h"
#include "MyDataCenter.h"

MyDataCenter::MyDataCenter()
	{
	// No implementation required
		iHtmlControl = NULL;
		iHistory = new (ELeave) CDesCArrayFlat(5);
	}

MyDataCenter::~MyDataCenter()
	{
	delete iMp3Stream;
	delete iDBStore;
	delete iDBInfo;
	delete iDBBook;
	delete iHistory;
	}

MyDataCenter* MyDataCenter::NewLC()
	{
	MyDataCenter* self = new (ELeave) MyDataCenter();
	CleanupStack::PushL(self);
	self->ConstructL();
	return self;
	}

MyDataCenter* MyDataCenter::NewL()
	{
	MyDataCenter* self = MyDataCenter::NewLC();
	CleanupStack::Pop(); // self;
	return self;
	}

void MyDataCenter::ConstructL()
	{

	}

void MyDataCenter::AddHistory(const TDesC& link)
{
//	CEikonEnv::Static()->InfoWinL(_L("his"), link);

	iHistory->AppendL(link);	
}

bool MyDataCenter::GoBack()
{
	//step2
	int count = iHistory->Count();
	
	if(count == 0)
		return false;

	iHistory->Delete(count-1);
	count = iHistory->Count();
	if(count == 0)
		return false;			

	ProcessLink((*iHistory)[count-1], false);
	
	return true;
}

void MyDataCenter::HandleBufImageLoadEventL(CBufferedImageDecoder* aDecoder, const TDesC& aFileName)
{
	c4_View view = iDBStore->View("image");
	
	TBuf8<256> str8;
	int len = aFileName.Length();
	str8.Copy(aFileName.Right(len-4));
	
	char* path = (char *)str8.Ptr();
	path[str8.Length()] = 0;
	
	int find = DBUtil::Static()->FindByStr(&view, "path", path);
	if(find < 0) find = 0;
	
	//CEikonEnv::Static()->InfoWinL(_L("tewt"), aFileName);
	TPtrC8 ptr = DBUtil::Static()->FieldUtf8Value(&view, "data", find);
	aDecoder->OpenL(ptr);
}

void MyDataCenter::HandleHtmlCtlEventL(const THtmlCtlEvent& aEvent)
	{
		if(aEvent.iType == THtmlCtlEvent::EOnClick)
		{
			CHtmlElement* link = aEvent.iElement->ElementByTag(_L("a"));
			if(aEvent.iElement->TagName() == _L("a")) 
				link = aEvent.iElement;
			
			if(link == NULL) 
			return;
		
			TBuf<200> href;
			link->GetProperty(KHStrHref, href);
			ProcessLink(href);
		}
	}

void MyDataCenter::Init(CHtmlControl* aHtmlControl, MPluginObserver* aObserver)
	{
	iObserver = aObserver;
	iHtmlControl = aHtmlControl;
	if(iHtmlControl == NULL)
		return;
	
	iHtmlControl->SetEventObserver(this);
	iDBBook = NULL;
	
	char drive = 'c';
#ifndef _DEBUG
	drive = 'e';
#endif

	TBuf8<256> path;

	//sound
	iMp3Stream = CStreamAudioEngine::NewL();
	//db
	char storepath[] = "c:\\data\\iRead\\iRead.bdb";
	storepath[0] = drive;
	iDBStore = new c4_Storage(storepath, true);		

	char infopath[] = "c:\\data\\iRead\\info.bdb";
	infopath[0] = drive;
	iDBInfo = new c4_Storage(infopath, true);		
	
	//html styles
	iHtmlControl->ClearStyleSheet();	
	c4_View view = iDBStore->View("style");
	
	for(int i = 0; i < view.GetSize(); i++){
		TPtrC8 style = DBUtil::Static()->FieldUtf8Value(&view, "value", i);
		HBufC* styleData = CnvUtfConverter::ConvertToUnicodeFromUtf8L(style);
		iHtmlControl->AddStyleSheetL(*styleData);
		CleanupStack::PushL(styleData);
		CleanupStack::PopAndDestroy(styleData); // styleData
	}
	
	iHtmlControl->ClearContent();
	LoadMemPage(iDBStore, _L("template.htm"));
	LoadMemPage(iDBStore, _L("index.htm"), true);	
	//LoadMemPage(_L("test.htm"));
	iHtmlControl->RefreshAndDraw();
	
	iHmListView.iControl = iHtmlControl;
	}

void MyDataCenter::LoadBook(const TDesC& dbname)
{
	if(iDBBook) delete iDBBook;
	TBuf8<100> filename;
	#ifdef _DEBUG		
		filename.Copy(_L8("c:\\data\\iRead\\"));
	#else
		filename.Copy(_L8("e:\\data\\iRead\\"));		
	#endif
		
	filename.Append(dbname);
	iCurrentDBFile.Copy(filename);

	TBool exist = BaflUtils::FileExists(CEikonEnv::Static()->FsSession(), iCurrentDBFile);
	if(exist == EFalse){
		CEikonEnv::Static()->InfoWinL(_L("Warnning"), _L("not found db file"));
		return;
	}
	
	char* filepath = (char *)filename.Ptr();
	filepath[filename.Length()] = '\0';//very important
	//	if(exist pah)
	iDBBook = new c4_Storage(filepath, false);		
	LoadMemPage(iDBBook, _L("book://index.htm"), true);
}

void MyDataCenter::ParsePage(const TDesC& paras)
	{

	CHtmlElement* item = iHtmlControl->Element(_L("dynlist"));
	if(item){
		int bufsize;
		item->GetProperty(KHStrBufSize, bufsize);
		if(bufsize > 50)
			return;
		iHmListView.ParsePage(iHtmlControl);
		return;
	}
	
	}

extern int gBinfilepos;
void MyDataCenter::PlayMp3(const TDesC& media)
{
	//iMp3Stream->OpenL(_L("c:\\data\\test.mp3"));
	//return;

	TPtrC audiofile = DBUtil::Static()->GetRealPath(media);

	c4_View view = iDBBook->View("audio");
	char audio[256];
	DBUtil::Static()->ConvertDesToStr(audiofile, audio);
	
	int find = DBUtil::Static()->FindByStr(&view, "name", audio);
	if(find < 0) return;
	
	c4_BytesProp binfield("data");
	c4_Bytes bin = binfield(view[find]);
		
	int mediaoffset = gBinfilepos;
	int mediarealsize = bin.Size();

	//TBuf<100> test;
	//test.Format(_L("%d,%d"), mediaoffset, mediarealsize);
	//CEikonEnv::Static()->InfoWinL(_L("Warnning"), test);
	
	iMp3Stream->OpenL(iCurrentDBFile, mediaoffset, mediarealsize);
}

bool MyDataCenter::ProcessLink(const TDesC& paras, bool addhistory)
{
	TBuf<256> path;
	path.Copy(paras);

	//convert into unix path
	for(int i = 0; i < path.Length(); i++){
		if(path[i] == '\\') path[i] = '/';
	}

	if(paras.Find(_L("post?")) == 0)
	{
		//Post(paras);
		return false;
	}

	if(paras.Find(_L(".rdm")) >= 0)
	{
		LoadBook(paras);
		return false;
	}

	if(paras.Find(_L(".mp3")) >= 0)
	{
		PlayMp3(paras);
		return false;
	}
	
	c4_Storage* store = iDBStore;
	if(DBUtil::Static()->FindBookPrefix(path))
			store = iDBBook;
		
	LoadMemPage(store, path, addhistory);
}

void MyDataCenter::LoadMemPage(c4_Storage* store, const TDesC& path, bool addhistory)
	{
		if(path.Find(_L("self?")) == 0)
			{
			//ProcessPageParameters(path);
			return;
			}


		TPtrC pagename = DBUtil::Static()->GetRealPath(path);	

		if(addhistory)
			AddHistory(path);	


		if(pagename == _L(""))
			return;
		
		//c4_View view = iDBStore->View("page");
		c4_View view = store->View("page");

		char szpagename[256];
		DBUtil::Static()->ConvertDesToStr(pagename, szpagename);
				
		int find = DBUtil::Static()->FindByStr(&view, "name", szpagename);
		
		if(find == -1){ 
			find = 0;
			CHtmlElement* pageContainer = iHtmlControl->Element(_L("iContent"));
			if(pageContainer){
				TBuf<200> errmsg;
				errmsg.Format(_L("Not found %S"), &path);
				pageContainer->SetProperty(KHStrInnerHtml, errmsg);
				iHtmlControl->RefreshAndDraw();
			}
			return;
		}
		
		TPtrC8 content8 = DBUtil::Static()->FieldUtf8Value(&view, "content", find);
		HBufC* pageData = CnvUtfConverter::ConvertToUnicodeFromUtf8L(content8);
		CleanupStack::PushL(pageData);

		CHtmlElement* pageContainer = iHtmlControl->Element(_L("iContent"));
		if(pageContainer){
			pageContainer->SetProperty(KHStrInnerHtml, KNullDesC);
		}

		if(pageContainer)
			pageContainer->SetProperty(KHStrInnerHtml, *pageData);
		else
			iHtmlControl->AppendContentL(*pageData);
			
		iHtmlControl->RefreshAndDraw();

			CleanupStack::PopAndDestroy(pageData); // pageData		

		//finally
		//default
		ParsePage(path);
	}

void MyDataCenter::TestMe()
	{
	}

void MyDataCenter::RenderListItemL(CHtmlElement* aElement, TInt aIndex)
{

}

TKeyResponse MyDataCenter::SuperHandleKeyEventL(const TKeyEvent& aKeyEvent, TEventCode aType )
{
	if( aType == EEventKeyDown )
		{ 
		TBuf<40> scanCode; 
		scanCode.AppendNum(aKeyEvent.iScanCode); 
			
		if(aKeyEvent.iScanCode == 165)//right softkeyback
			{
			//CancelLoading();

			//if(IsMenuVisible())
			//	HideMenu();
			
			if(GoBack() == false)
				{
					if(iObserver)
					{
						CEikonEnv::Static()->InfoMsg(scanCode);
						iObserver->UnloadPlugin(NULL);
						return EKeyWasConsumed;
					}
					else{
						CAknAppUiBase* appui = (CAknAppUiBase*)CEikonEnv::Static()->EikAppUi();
						appui->Exit();
						return EKeyWasConsumed;
					}
				}
			else
				return EKeyWasConsumed;
				

			}
		}
	
	return EKeyWasNotConsumed;
}
